[小ネタ] CloudWatch Logsのログイベント総数をカウントしてみた
AWSを愛する皆さま、こんにちは。 最近身体を鍛えたいと思っているコンサルティング部の西野(@xiye_gen)です。
ログイベント総数を数える方法
CloudWatch LogsのAPIを利用します。Boto3を使って実装してみました。
サンプルコード
import boto3 import time # 13桁のunixtime(msec)でqueryの範囲を指定 START_TIME = 1569855600000 # 2019/10/01 00:00:00 END_TIME = 1572533999000 # 2019/10/31 23:59:59 # クエリごとの実行待ち時間(sec) WAIT_TIME_PER_QUERY = 1 client = boto3.client('logs') describe_log_groups_paginator = client.get_paginator('describe_log_groups') def generate_log_group_list(paginator): page_iterator = paginator.paginate() log_group_list = [] for page in page_iterator: for log_group in page['logGroups']: log_group_name = log_group['logGroupName'] log_group_list.append(log_group_name) print('Number of log groups: {}'.format(len(log_group_list))) print(log_group_list) return log_group_list def start_query(log_group): response = client.start_query( logGroupName=log_group, startTime=START_TIME, endTime=END_TIME, queryString='stats count(*)', limit=10000 ) return response def get_query_results(query_id): response = client.get_query_results( queryId=query_id ) return response def count_log_events(log_group_list): query_id_list = [] total_number_of_log_events = 0 for i in range(len(log_group_list)): print('Querying [{}] ({}/{})'.format(log_group_list[i], i + 1, len(log_group_list))) response = start_query(log_group_list[i]) time.sleep(WAIT_TIME_PER_QUERY) query_id_list.append(response['queryId']) print('Waiting for query completion.') time.sleep(10) for i in range(len(query_id_list)): results = get_query_results(query_id_list[i]) number_of_log_events = results['results'][0][0]['value'] print('{}:{} ({}/{})'.format(query_id_list[i], number_of_log_events, i + 1, len(log_group_list))) total_number_of_log_events += int(number_of_log_events) return total_number_of_log_events log_group_list = generate_log_group_list(describe_log_groups_paginator) total_number_of_log_events = count_log_events(log_group_list) print('Total number of log events: {}'.format(total_number_of_log_events))
変数
変数名 | 内容 |
---|---|
START_TIME | クエリ範囲の開始時刻(13桁のunixtime) |
END_TIME | クエリ範囲の開始時刻(13桁のunixtime) |
WAIT_TIME_PER_QUERY | クエリごとの実行後の待ち時間(sec) |
CloudWatch Logs Insightのクエリ同時実行数がデフォルトで最大4であるため、time.sleep(WAIT_TIME_PER_QUERY)
で制限をかけます。
実行時にaccount maximum query concurrency limit of 4 reached
というエラーが出た場合はWAIT_TIME_PER_QUERYの値を増やしてください。
解説
- describe_log_groups()のpaginatorでロググループ名のリストを作成
- 各ロググループに対してクエリ(
stats count(*)
)を実行し、クエリIDのリストを作成 - クエリIDをもとに結果の問い合わせをし、各ロググループにおけるログイベント数を合計
やってみた
事前準備
あらかじめアカウント内に3600個のログイベントを作成します。
- ロググループを60個作成(log_group_001〜log_group_060)
- 各ロググループ内にログストリームを60個作成
- 各ログストリームに一つのログイベントを作成
実行結果
$ python count_log_events.py Number of log groups: 60 ['log_group_001', 'log_group_002', 'log_group_003', 'log_group_004', 'log_group_005', 'log_group_006', 'log_group_007', 'log_group_008', 'log_group_009', 'log_group_010', 'log_group_011', 'log_group_012', 'log_group_013', 'log_group_014', 'log_group_015', 'log_group_016', 'log_group_017', 'log_group_018', 'log_group_019', 'log_group_020', 'log_group_021', 'log_group_022', 'log_group_023', 'log_group_024', 'log_group_025', 'log_group_026', 'log_group_027', 'log_group_028', 'log_group_029', 'log_group_030', 'log_group_031', 'log_group_032', 'log_group_033', 'log_group_034', 'log_group_035', 'log_group_036', 'log_group_037', 'log_group_038', 'log_group_039', 'log_group_040', 'log_group_041', 'log_group_042', 'log_group_043', 'log_group_044', 'log_group_045', 'log_group_046', 'log_group_047', 'log_group_048', 'log_group_049', 'log_group_050', 'log_group_051', 'log_group_052', 'log_group_053', 'log_group_054', 'log_group_055', 'log_group_056', 'log_group_057', 'log_group_058', 'log_group_059', 'log_group_060'] Querying [log_group_001] (1/60) Querying [log_group_002] (2/60) Querying [log_group_003] (3/60) Querying [log_group_004] (4/60) (中略) Querying [log_group_057] (57/60) Querying [log_group_058] (58/60) Querying [log_group_059] (59/60) Querying [log_group_060] (60/60) Waiting for query completion. 2b91099b-230b-48f4-a932-5396b3c88dff:60 (1/60) a8d92b0a-4a63-4fe5-ad98-e61ca52d3bef:60 (2/60) 1292bda9-e9ee-49d6-b52b-e115bb701740:60 (3/60) f045733f-042f-4cdb-954b-8e737ee7ecec:60 (4/60) (中略) 00cde834-7cb4-447f-9904-eba07c61ab7e:60 (57/60) 3f794951-6916-44f0-98ef-796e4369d341:60 (58/60) f9726b98-5072-41a4-9388-15967abab4dc:60 (59/60) aa7b27ad-fe59-4e18-a730-df5baee2971a:60 (60/60) Total number of log events: 3600
ログイベントの総数を取得できました。
注意点
APIの仕様上、単一のクエリから返されるログイベントの最大数は 10000 です。 本エントリに掲載したサンプルコードの場合、クエリ:ロググループの関係が1:1となっているため、ロググループ内のログイベント数が10000を超えた場合正確な総数を取得できません。
参考:Amazon CloudWatch Logs API Reference / StartQuery
終わりに
このブログがほんの少しでも世界を良くできれば嬉しいです。 コンサルティング部の西野(@xiye_gen)がお送りしました。